package view;

import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JFrame;

import main.Log;
import model.Executable;
import model.GameClock;
import model.entity.Avatar;
import model.entity.stats.Stat;
import model.entity.stats.StatSet;
import model.entity.stats.StatType;
import model.handler.DeathHandler;
import model.interactionhandler.InteractionContainer;
import model.map.Direction;
import model.map.GameMap;
import model.map.Location;
import model.map.MovementType;
import model.map.World;
import controller.AvatarController;
import controller.CameraController;
import controller.InteractionController;

public class VinnysAwesomeTest {
	
	public static void main(String args[]) {
		testGrid();
//		testGameClock();
//		testEquipmentOverlay();
	}
	
	public static void testEquipmentOverlay() {
		EquipmentOverlay eo = new EquipmentOverlay( new Dimension(800,600), null, 
				new Point(200,200), null);
		
		GameWindow gw = new GameWindow("AlejandroTests");
		gw.addOverlay( "testMapOverlay", eo );
		gw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gw.setSize( 800, 600 );
		gw.addMouseListener( GameButtonRegistry.getInstance() );
		gw.setVisible(true);
	}
	
	public static void testGrid() {
		//Avatar avatar = createDummyAvatar();
		
		
		GameMap gm = new GameMap(7);
		World.getInstance().addMap( gm );
		World.getInstance().setCurrentMap( gm );
		//gm.addEntity( avatar );
		
		//World.getInstance().setPlayer( avatar );
		
		MapOverlay mo = new MapOverlay( new Dimension(800,600), gm, new Location(13,13) );
		InteractionOverlay io = new InteractionOverlay( new Dimension(800,600), InteractionContainer.getInstance() );
		loadTestImages();//loads images into ModelToImage classes
		
		GameWindow gw = new GameWindow("AlejandroTests");
		gw.setSize( 800, 600 );
		gw.addOverlay( "testMapOverlay", mo );
		gw.addOverlay( "testInteractionoverlay", io);
		initializeRefresh( gw );
		
		DeathHandler.getInstance().start();
	
		
		CameraController cc = new CameraController( mo, gw );
		AvatarController ac = new AvatarController( World.getInstance().getPlayer(), gw, mo, InteractionContainer.getInstance() );
		InteractionController ic = new InteractionController( io, gw, InteractionContainer.getInstance() );
		
		gw.addMouseListener( GameButtonRegistry.getInstance() );
		
		gw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gw.setVisible(true);
		
		World.getInstance().getCurrentMap().getFogOfWar().update();
	}
	
	public static Avatar createDummyAvatar() {
		ArrayList<MovementType> mt = new ArrayList<MovementType>();
		mt.add( MovementType.GRASS );
		StatSet stats = new StatSet();
		stats.addStat(StatType.MOVEMENTSPEED, new Stat(10, StatType.MOVEMENTSPEED));
		
		Avatar avatar = new Avatar("entity", Direction.S, new Location(11,13), stats, mt , null, null, null, false);
		return avatar;
	}
	
	public static void initializeRefresh( final GameWindow gw ) {
		GameClock.getInstance().scheduleAtFixedRate( 1, new Executable() {
			@Override
			public void execute() {
				gw.repaint();
			}
		} );
	}
	
	public static void loadTestImages() {
		ModelToImage.addImage( "Unpassable", "./Data/imgs/grayTile.png" );
		ModelToImage.addImage( "Grass", "./Data/imgs/greenTile.png" );
		ModelToImage.addImage( "obstacle", "./Data/imgs/obstacle.png" );
		ModelToImage.addImage( "areaEffect", "./Data/imgs/areaEffect.png" );
		ModelToImage.addImage( "decal", "./Data/imgs/decal.png" );
		ModelToImage.addImage( "item", "./Data/imgs/item.png" );
		
		//add entity
		Map<Direction, String> m0 = new HashMap<Direction, String>();
		m0.put(Direction.S, "./Data/imgs/avatar_s.png");
		m0.put(Direction.SE, "./Data/imgs/avatar_se.png");
		m0.put(Direction.SW, "./Data/imgs/avatar_sw.png");
		m0.put(Direction.N, "./Data/imgs/avatar_n.png");
		m0.put(Direction.NE, "./Data/imgs/avatar_ne.png");
		m0.put(Direction.NW, "./Data/imgs/avatar_nw.png");
		DirectionalModelToImage.addImage("entity", m0);
		//add pet
		Map<Direction, String> m3 = new HashMap<Direction, String>();
		m3.put(Direction.S, "./Data/imgs/Pet.png");
		m3.put(Direction.SE, "./Data/imgs/Pet.png");
		m3.put(Direction.SW, "./Data/imgs/Pet.png");
		m3.put(Direction.N, "./Data/imgs/Pet.png");
		m3.put(Direction.NE, "./Data/imgs/Pet.png");
		m3.put(Direction.NW, "./Data/imgs/Pet.png");
		DirectionalModelToImage.addImage("Pet", m3);
		// add some devils
		Map<Direction, String> m4 = new HashMap<Direction, String>();
		m4.put(Direction.S, "./Data/imgs/satan_s.png");
		m4.put(Direction.SE, "./Data/imgs/satan_se.png");
		m4.put(Direction.SW, "./Data/imgs/satan_sw.png");
		m4.put(Direction.N, "./Data/imgs/satan_n.png");
		m4.put(Direction.NE, "./Data/imgs/satan_ne.png");
		m4.put(Direction.NW, "./Data/imgs/satan_nw.png");
		DirectionalModelToImage.addImage("satan", m4);
		//add vehicle
		Map<Direction, String> m1 = new HashMap<Direction, String>();
		m1.put(Direction.S, "./Data/imgs/vehicle.png");
		DirectionalModelToImage.addImage("vehicle", m1);
		/*add projectile
		Map<Direction, String> m2 = new HashMap<Direction, String>();
		m2.put(Direction.S, "./Data/imgs/projectile.png");
		DirectionalModelToImage.addImage("projectile", m2);
		*/
		
		//add projectile
		Map<Direction, String> m2 = new HashMap<Direction, String>();
		m2.put(Direction.S, "./Data/imgs/projectile.png");
		m2.put(Direction.SE, "./Data/imgs/projectile.png");
		m2.put(Direction.SW, "./Data/imgs/projectile.png");
		m2.put(Direction.N, "./Data/imgs/projectile.png");
		m2.put(Direction.NE, "./Data/imgs/projectile.png");
		m2.put(Direction.NW, "./Data/imgs/projectile.png");
		
		DirectionalModelToImage.addImage("projectile", m2);
		
		//add semitransparent tile
		ModelToImage.addImage( "semitransparentTile", "./Data/imgs/semitransparentHexagon.png" );
		
	}

	public static void testGameClock() {
		final GameClock c = GameClock.getInstance();
		Log.out( Log.VIEW, "Before first executable.");
		final Executable e = new Executable() {
			@Override
			public void execute() {
				Log.out( Log.VIEW, "In first executable.");
			}
		};
		Executable e2 = new Executable() {
			@Override
			public void execute() {
				Log.out( Log.VIEW, "In second executable: remove first executable.");
				c.remove( e );
			}
		};
		c.scheduleAtFixedRate(80, e);
		c.schedule(410, e2);
	}
}